home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / vbcc / main.c < prev    next >
C/C++ Source or Header  |  1995-11-23  |  16KB  |  459 lines

  1. #include "vbc.h"
  2.  
  3. int endok=1;
  4. int line,errors;
  5.  
  6. char *multname[]={"","s"};
  7. void raus(void)
  8. /*  Beendet das Programm                                            */
  9. {
  10.     if(DEBUG) printf("raus()");
  11.     if(!endok) printf("unexpected end of file\n");
  12.     if(errors) printf("%d error%s found!\n",errors,multname[errors>1]);
  13.     while(nesting>=0) leave_block();
  14.     if(in) fclose(in);
  15.     if(out) fclose(out);
  16.     if(ic1) fclose(ic1);
  17.     if(ic2) fclose(ic2);
  18.     if(endok&&!errors) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE);
  19. }
  20. void translation_unit(void)
  21. /*  bearbeitet translation_unit                                     */
  22. /*  hier z.Z. nur provisorisch                                      */
  23. {
  24.     while(1){
  25.         killsp();
  26.         if(!isalpha(*s)&&*s!='_'){
  27.             if(*s!=EOF) error(0);
  28.             raus();
  29.         }
  30.         endok=0;
  31.         var_declaration();
  32.         endok=1;
  33.     }
  34. }
  35.  
  36. void dontwarn(char *p)
  37. /*  schaltet flags fuer Meldung auf DONTWARN    */
  38. {
  39.     int i;
  40.     if(*p!='=') error(4,"-dontwarn");
  41.     i=atoi(p+1);
  42.     if(i>=err_num) error(159,i);
  43.     if(err_out[i].flags&(ANSIV|FATAL)) error(160,i);
  44.     err_out[i].flags|=DONTWARN;
  45. }
  46.  
  47. extern char *copyright;
  48.  
  49. int main(int argc,char *argv[])
  50. {
  51.     int i,j,fname=0;
  52.     c_flags_val[9].f=dontwarn;
  53.     for(i=1;i<argc;i++){
  54.         if(*argv[i]!='-'){  /*  kein Flag   */
  55.             if(fname){
  56.                 error(1);
  57.             }else fname=i;
  58.         }else{
  59.             int flag=0;
  60.             for(j=0;j<MAXCF;j++){
  61.                 size_t l;
  62.                 if(!c_flags_name[j]) continue;
  63.                 l=strlen(c_flags_name[j]);
  64.                 if(l>0&&!strncmp(argv[i]+1,c_flags_name[j],l)){
  65.                     flag=1;
  66.                     if((c_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  67.                     c_flags[j]|=USEDFLAG;
  68.                     if(c_flags[j]&STRINGFLAG){
  69.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  70.                         c_flags_val[j].p=&argv[i][l+2];
  71.                     }
  72.                     if(c_flags[j]&VALFLAG){
  73.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  74.                         c_flags_val[j].l=atol(&argv[i][l+2]);
  75.                     }
  76.                     if(c_flags[j]&FUNCFLAG) c_flags_val[j].f(&argv[i][l+1]);
  77.                 }
  78.             }
  79.             for(j=0;j<MAXGF;j++){
  80.                 size_t l;
  81.                 if(!g_flags_name[j]) continue;
  82.                 l=strlen(g_flags_name[j]);
  83.                 if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){
  84.                     flag=1;
  85.                     if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  86.                     g_flags[j]|=USEDFLAG;
  87.                     if(g_flags[j]&STRINGFLAG){
  88.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  89.                         g_flags_val[j].p=&argv[i][l+2];
  90.                     }
  91.                     if(g_flags[j]&VALFLAG){
  92.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  93.                         g_flags_val[j].l=atol(&argv[i][l+2]);
  94.                     }
  95.                     if(g_flags[j]&FUNCFLAG) g_flags_val[j].f(&argv[i][l+1]);
  96.                 }
  97.             }
  98.             if(!flag){error(5,argv[i]);}
  99.         }
  100.     }
  101.     if(!(c_flags[6]&USEDFLAG)) printf(copyright);
  102.     if(!(c_flags[8]&USEDFLAG)) c_flags_val[8].l=10; /* max. Fehlerzahl */
  103.     if(!fname){error(6);}
  104.     inname=argv[fname];
  105.     if(!init_cg()) exit(EXIT_FAILURE);
  106.     in=fopen(inname,"r");
  107.     if(!in) {error(7,inname);}
  108.     out=open_out(inname,"asm");
  109.     if(!out){fclose(in);exit(EXIT_FAILURE);}
  110.     if(c_flags[2]&USEDFLAG) ic1=open_out(inname,"ic1");
  111.     if(c_flags[3]&USEDFLAG) ic2=open_out(inname,"ic2");
  112.     if(c_flags[4]&USEDFLAG) DEBUG=c_flags_val[4].l; else DEBUG=0;
  113.     switch_count=0;break_label=0;
  114.     *string=0;s=string;line=0;
  115.     killsp();
  116.     nesting=-1;enter_block();
  117.     translation_unit();
  118. }
  119.  
  120. void prd(FILE *o,struct Typ *p)
  121. /* Gibt einen Typ auf dem Bildschirm aus    */
  122. {
  123.     int f;
  124.     if(!p) {fprintf(o,"leerer Typ ");return;}
  125.     f=p->flags;
  126.     fprintf(o,"(Sizeof=%d,flags=%d)",szof(p),f);
  127.     if(f&UNCOMPLETE) {fprintf(o,"Unkompletter Typ ");f&=~UNCOMPLETE;}
  128.     if(f&CONST) {fprintf(o,"const ");f&=~CONST;}
  129.     if(f&VOLATILE) {fprintf(o,"volatile ");f&=~VOLATILE;}
  130.     if(f&UNSIGNED) {fprintf(o,"unsigned ");f&=~UNSIGNED;}
  131.     if(f==FUNKT) {fprintf(o,"Funktion mit Parametern (");
  132.                   prl(o,p->exact);
  133.                   fprintf(o,") und Rueckgabe ");prd(o,p->next);return;}
  134.     if(f==STRUCT){fprintf(o,"Struktur mit Komponenten {");
  135.                   if(p->flags&UNCOMPLETE) fprintf(o,"%s} ",(char *)p->exact);
  136.                    else {prl(o,p->exact);fprintf(o,"} ");}
  137.                   return;
  138.     }
  139.     if(f==UNION) {fprintf(o,"Union mit Komponenten {");
  140.                   if(p->flags&UNCOMPLETE) fprintf(o,"%s} ",(char *)p->exact);
  141.                    else {prl(o,p->exact);fprintf(o,"} ");return;}
  142.     }
  143.     if(f==POINTER) {fprintf(o,"Zeiger auf ");prd(o,p->next);return;}
  144.     if(f==ARRAY) {fprintf(o,"Array [%d] von ",p->size);prd(o,p->next);return;}
  145.     fprintf(o,"%s",typname[f]);
  146. }
  147. void prl(FILE *o,struct struct_declaration *p)
  148. /* Gibt eine struct_declaration auf dem Bildschirm aus */
  149. {
  150.     int i;
  151.     for(i=0;i<p->count;i++) {fprintf(o,"(%d,%s) ",i,p->sl[i].identifier); prd(o,p->sl[i].styp);}
  152. }
  153. void freetyp(struct Typ *p)
  154. /* Gibt eine Typ-Liste frei, aber keine struct_declaration oder so */
  155. {
  156.     int f;struct Typ *merk;
  157.     if(DEBUG&8){printf("freetyp: ");prd(stdout,p);printf("\n");}
  158.     while(p){
  159.         merk=p->next;
  160.         f=p->flags&15;
  161.         if(merk&&f!=ARRAY&&f!=POINTER&&f!=FUNKT){ierror(0);return;}
  162.         free(p);
  163.         p=merk;
  164.     }
  165. }
  166. void cpbez(char *m)
  167. /* kopiert den naechsten Bezeichner von s nach m */
  168. {
  169.     if(DEBUG&128) printf("Before cpbez:%s\n",s);
  170.     while(isalpha(*s)||isnum(*s)||*s=='_') *m++=*s++;
  171.     *m++=0;
  172.     if(DEBUG&128) printf("After cpbez:%s\n",s);
  173. }
  174. void cpnum(char *m)
  175. /* kopiert die naechste int-Zahl von s nach m   */
  176. /* muss noch erheblich erweiter werden          */
  177. {
  178.     if(DEBUG&128) printf("Before cpnum:%s\n",s);
  179.     while(isnum(*s)) *m++=*s++;
  180.     *m++=0;
  181.     if(DEBUG&128) printf("After cpnum:%s\n",s);
  182.  
  183. }
  184. void killsp(void)
  185. /*  Ueberspringt Fuellzeichen                   */
  186. {
  187.     if(DEBUG&128) printf("Before killsp:%s\n",s);
  188.     if(*s==EOF) raus();
  189.     while(*s==' '||*s=='\t'||*s=='\n'||*s=='\r'){
  190. /*        if(*s=='\n') {line++;if(DEBUG&1) printf("Line %d\n",line);}*/
  191.         s++;
  192.     }
  193.     if(*s==0){
  194.         do{
  195.             if(!fgets(string,MAXINPUT,in)){
  196.                 /*raus();*/
  197.                 s=string;*s=EOF;
  198.                 return;
  199.             }else{line++;if(DEBUG&1) printf("Line %d\n",line);}
  200.             s=string;
  201.         }while(*s=='#');
  202.         killsp();
  203.     }
  204.     if(DEBUG&128) printf("After killsp:%s\n",s);
  205. }
  206. int szof(struct Typ *t)
  207. /*  liefert die benoetigte Groesse eines Typs in Bytes      */
  208. /*  maschinenabhaengig                                      */
  209. {
  210.     int i=t->flags,j,size,m,f;
  211.     /* wofuer was das hier gedacht ?    */
  212. /*    if(type_uncomplete(t)) return(0);*/
  213.     if(i&UNCOMPLETE) return(0);
  214.     if((i&15)==POINTER) return(4);
  215.     if((i&15)==ARRAY) return((t->size)*szof(t->next));
  216.     if((i&15)==UNION){
  217.         for(j=0,size=0;j<t->exact->count;j++){
  218.             m=szof(t->exact->sl[j].styp);
  219.             if(m==0) return(0);
  220.             if(m>size) size=m;
  221.         }
  222.         return(((size+align[UNION]-1)/align[UNION])*align[UNION]); /* align */
  223.     }
  224.     if((i&15)==STRUCT){
  225.         for(j=0,size=0;j<t->exact->count;j++){
  226.             m=szof(t->exact->sl[j].styp);
  227.             if(m==0) return(0);
  228.             f=(t->exact->sl[j].styp->flags)&15;
  229.             size=((size+align[f]-1)/align[f])*align[f];
  230.             size+=m;
  231.         }
  232.         return(((size+align[STRUCT]-1)/align[STRUCT])*align[STRUCT]);
  233.     }
  234.     if(DEBUG&2) printf("sizeof(%d)=%d\n",i&15,sizetab[i&15]);
  235.     return(sizetab[i&15]);
  236. }
  237. void enter_block(void)
  238. /*  Setzt Zeiger/Struckturen bei Eintritt in neuen Block    */
  239. {
  240.     if(nesting>=MAXN){error(9,nesting);return;}
  241.     nesting++;
  242.     if(DEBUG&1) printf("enter block %d\n",nesting);
  243.     first_ilist[nesting]=last_ilist[nesting]=0;
  244.     first_sd[nesting]=last_sd[nesting]=0;
  245.     first_si[nesting]=last_si[nesting]=0;
  246.     first_var[nesting]=last_var[nesting]=0;
  247.     if(nesting==1){
  248.         first_llist=last_llist=0;
  249.         first_clist=last_clist=0;
  250.         merk_varf=merk_varl=0;
  251.         merk_ilistf=merk_ilistl=0;
  252.         merk_sif=merk_sil=0;
  253.         merk_sdf=merk_sdl=0;
  254.         afterlabel=0;
  255.     }
  256. }
  257. void leave_block(void)
  258. /*  Setzt Zeiger/Struckturen bei Verlassen eines Blocks     */
  259. {
  260.     if(nesting<0){error(10);return;}
  261.     if(DEBUG&1) printf("leave block %d\n",nesting);
  262.     if(nesting>0){
  263.         if(merk_varl) merk_varl->next=first_var[nesting]; else merk_varf=first_var[nesting];
  264.         if(last_var[nesting]) merk_varl=last_var[nesting];
  265.         if(merk_sil) merk_sil->next=first_si[nesting]; else merk_sif=first_si[nesting];
  266.         if(last_si[nesting]) merk_sil=last_si[nesting];
  267.         if(merk_sdl) merk_sdl->next=first_sd[nesting]; else merk_sdf=first_sd[nesting];
  268.         if(last_sd[nesting]) merk_sdl=last_sd[nesting];
  269.         if(merk_ilistl) merk_ilistl->next=first_ilist[nesting]; else merk_ilistf=first_ilist[nesting];
  270.         if(last_ilist[nesting]) merk_ilistl=last_ilist[nesting];
  271.     }
  272.     if(nesting==1){
  273.         if(merk_varf) gen_vars(merk_varf);
  274.         if(first_llist) free_llist(first_llist);
  275.         if(first_clist) free_clist(first_clist);
  276.         if(merk_varf) free_var(merk_varf);
  277.         if(merk_sif) free_si(merk_sif);
  278.         if(merk_sdf) free_sd(merk_sdf);
  279.         if(merk_ilistf) free_ilist(merk_ilistf);
  280.     }
  281.     if(nesting==0){
  282.         if(first_var[0]) gen_vars(first_var[0]);
  283.         if(first_var[0]) free_var(first_var[0]);
  284.         if(first_sd[0]) free_sd(first_sd[0]);
  285.         if(first_si[0]) free_si(first_si[0]);
  286.         if(first_ilist[0]) free_ilist(first_ilist[0]);
  287.     }
  288.     nesting--;
  289. }
  290. void pra(FILE *f,struct argument_list *p)
  291. /*  Gibt argument_list umgekehrt auf Bildschirm aus             */
  292. {
  293.     if(p->next){ pra(f,p->next);fprintf(f,",");}
  294.     if(p->arg) pre(f,p->arg);
  295. }
  296. void pre(FILE *f,np p)
  297. /*  Gibt expression auf Bildschirm aus                          */
  298. {
  299.     int c;
  300.     c=p->flags;
  301.     if(p->sidefx) fprintf(f,"/");
  302.     if(p->lvalue) fprintf(f,"|");
  303.     if(c==CALL){fprintf(f,"call-function(");pre(f,p->left);fprintf(f,")(");
  304.                 if(p->alist) pra(f,p->alist);
  305.                 fprintf(f,")");return;}
  306.     if(c==CAST){fprintf(f,"cast(");pre(f,p->left);
  307.                 fprintf(f,"->");prd(f,p->ntyp);
  308.                 fprintf(f,")");return;}
  309.     if(c==MEMBER){if(p->identifier) fprintf(f,".%s",p->identifier);return;}
  310.     if(c==IDENTIFIER){if(p->identifier) fprintf(f,"%s",p->identifier);
  311.         fprintf(f,"+");printval(f,&p->val,LONG,1); return;}
  312.     fprintf(f,"%s(",ename[c]);
  313.     if(p->left) pre(f,p->left);
  314.     if(p->right){
  315.         fprintf(f,",");
  316.         pre(f,p->right);
  317.     }
  318.     fprintf(f,")");
  319.     if(c==CEXPR||c==PCEXPR){fprintf(f,"(value="); printval(f,&p->val,p->ntyp->flags,1); fprintf(f,")");}
  320. }
  321. void printval(FILE *f,union atyps *p,int t,int verbose)
  322. /*  Gibt atyps aus                                      */
  323. {
  324.     if(t==CHAR){if(verbose)fprintf(f,"C");vlong=zc2zl(p->vchar);printzl(f,vlong);}
  325.     if(t==(UNSIGNED|CHAR)){if(verbose)fprintf(f,"UC");vulong=zuc2zul(p->vuchar);printzul(f,vulong);}
  326.     if(t==SHORT){if(verbose)fprintf(f,"S");vlong=zs2zl(p->vshort);printzl(f,vlong);}
  327.     if(t==(UNSIGNED|SHORT)){if(verbose) fprintf(f,"US");vulong=zus2zul(p->vushort);printzul(f,vulong);}
  328.     if(t==FLOAT){if(verbose)fprintf(f,"F");vdouble=zf2zd(p->vfloat);printzd(f,vdouble);}
  329.     if(t==DOUBLE){if(verbose)fprintf(f,"D");printzd(f,p->vdouble);}
  330.     if(t==INT){if(verbose)fprintf(f,"I");vlong=zi2zl(p->vint);printzl(f,vlong);}
  331.     if(t==LONG){if(verbose)fprintf(f,"L");printzl(f,p->vlong);}
  332.     if(t==(UNSIGNED|INT)){if(verbose)fprintf(f,"UI");vulong=zui2zul(p->vuint);printzul(f,vulong);}
  333.     if(t==(UNSIGNED|LONG)){if(verbose)fprintf(f,"UL");printzul(f,p->vulong);}
  334.     /*  das hier ist nicht wirklich portabel    */
  335.     if(t==POINTER){if(verbose)fprintf(f,"P");vulong=zp2zul(p->vpointer);printzul(f,vulong);}
  336. }
  337. void pric2(FILE *f,struct IC *p)
  338. /*  Gibt ein IC aus */
  339. {
  340.     if(p->next&&p->next->prev!=p) {ierror(0);exit(EXIT_FAILURE);}
  341.     if(p->code>=LABEL&&p->code<=BRA){
  342.         if(p->code==LABEL) fprintf(f,"L%d",p->typf);
  343.         else fprintf(f,"\t\t%s L%d",ename[p->code],p->typf);
  344.     }else{
  345.         fprintf(f,"\t\t%s ",ename[p->code]);
  346.         if(p->typf&UNSIGNED) fprintf(f,"unsigned ");
  347.         if(p->typf) fprintf(f,"%s ",typname[p->typf&15]);
  348.         probj(f,&p->q1,p->typf,1);
  349.         if(p->q2.flags){fprintf(f,",");probj(f,&p->q2,p->typf,1);}
  350.         if(p->z.flags){fprintf(f,"->");probj(f,&p->z,p->typf,1);}
  351.         if(p->code==ASSIGN||p->code==PUSH||p->code==POP) fprintf(f," size=%d",p->q2.reg);
  352.     }
  353.     fprintf(f,"\n");
  354. }
  355. void pric(FILE *f,struct IC *p)
  356. /*  Gibt IC-Liste auf dem Bildschirm aus                */
  357. {
  358.     while(p){
  359.         pric2(f,p);
  360.         p=p->next;
  361.     }
  362. }
  363.  
  364. char *errstr[]={"","warning","error"};
  365.  
  366. void error(int errn,...)
  367. /*  Behandelt Ausgaben wie Fehler und Meldungen */
  368. {
  369.     int type=0;
  370.     va_list vl;
  371.     if(err_out[errn].flags&DONTWARN) return;
  372.     va_start(vl,errn);
  373.     if(err_out[errn].flags&WARNING) type=1;
  374.     if(err_out[errn].flags&ERROR) type=2;
  375.     if(c_flags[7]&USEDFLAG){
  376.         if(err_out[errn].flags&ANSIV) type=2; else type=0;
  377.     }
  378.     if(type){
  379.         {if(*string==EOF) printf(">EOF\n"); else printf(">%s",string);}
  380.         printf("%s %d in line %d of %s: ",errstr[type],errn,line,inname);
  381.     }
  382.     if(type||(err_out[errn].flags&MESSAGE)){
  383.         vprintf(err_out[errn].text,vl);
  384.         printf("\n");
  385.     }
  386.     va_end(vl);
  387.     if(type==2){
  388.         errors++;
  389.         if(c_flags_val[8].l&&c_flags_val[8].l<=errors)
  390.             {printf("Maximum number of errors reached!\n");raus();}
  391.     }
  392.     if(err_out[errn].flags&FATAL){printf("aborting...\n");raus();}
  393. }
  394. void printzl(FILE *f,zlong x)
  395. /*  Konvertiert zlong nach ASCII                        */
  396. /*  basiert noch einigermassen auf                      */
  397. /*  Zweierkomplementdarstellung (d.h. -MIN>MAX)         */
  398. /*  Ausserdem muss max(abs(long))<=max(unsigned long)   */
  399. {
  400.     zlong zl;zulong zul;
  401.     zl=l2zl(0L);
  402.     if(zlleq(x,zl)&&!zleq(x)){
  403.         fprintf(f,"-");zl=zul2zl(t_max[LONG]);
  404.         if(zlleq(x,zlneg(zl))&&!zleqto(x,zlneg(zl))){
  405.         /*  aufpassen, da -x evtl. >LONG_MAX    */
  406.             zul=t_max[LONG];
  407.             x=zladd(x,zl);
  408.         } else zul=ul2zul(0UL);
  409.         x=zlneg(x);
  410.         vulong=zl2zul(x);
  411.         zul=zuladd(zul,vulong);
  412.     }else zul=zl2zul(x);
  413.     printzul(f,zul);
  414. }
  415. void printzul(FILE *f,zulong x)
  416. /*  Konvertiert zulong nach ASCII                       */
  417. {
  418.     zulong zul;unsigned long l;
  419.     if(DEBUG&64) printf("printzul:%lu\n",x);
  420.     zul=ul2zul(10UL);
  421.     if(!zuleq(zuldiv(x,zul))) printzul(f,zuldiv(x,zul));
  422.     zul=zulmod(x,zul);l=zul2ul(zul);
  423.     fprintf(f,"%c",(int)(l+'0'));
  424. }
  425. void printzd(FILE *f,zdouble x)
  426. /*  Konvertiert zdouble nach ASCII, noch nicht fertig   */
  427. {
  428.     fprintf(f,"sorry, floating point not yet");
  429. }
  430. FILE *open_out(char *name,char *ext)
  431. /*  Haengt ext an name an und versucht diese File als output zu oeffnen */
  432. {
  433.     char *s,*p;FILE *f;
  434.     s=(char *)mymalloc(strlen(name)+strlen(ext)+1);
  435.     strcpy(s,name);
  436.     p=s+strlen(s);
  437.     while(p>=s){
  438.         if(*p=='.'){*p=0;break;}
  439.         p--;
  440.     }
  441.     strcat(s,".");
  442.     strcat(s,ext);
  443.     f=fopen(s,"w");
  444.     if(!f) printf("Couldn't open <%s> for output!\n",s);
  445.     free(s);
  446.     return(f);
  447. }
  448. void *mymalloc(size_t size)
  449. /*  Belegt Speicher mit Abfrage     */
  450. {
  451.     void *p;
  452.     if(!(p=malloc(size))){
  453.         error(12);
  454.         raus();
  455.     }
  456.     return(p);
  457. }
  458.  
  459.